﻿Imports System.IO.Ports
Imports Microsoft.Win32


Class MainWindow
    Private Color1 As Color = Colors.Black
    Private Color2 As Color = Colors.Gray


    Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
        ScanForPorts()

        DPT_Types = EIBData.EIBDataDPT_Info.GetDPTBases()
        EIS_Types = EIBData.EIBDataEIS_Info.GetEISBases

        lbLog_SelectionChanged(Nothing, Nothing)

        lbLog.DataContext = Logger
        AddHandler Logger.CollectionChanged, Sub()
                                                 lvLog.DataContext = From entry In Logger Where TypeOf entry Is EIBBusMessageLogEntry
                                             End Sub
    End Sub

    Private Sub btnRescanPorts_Click(sender As Object, e As RoutedEventArgs) Handles btnRescanPorts.Click
        ScanForPorts()
    End Sub

    Private Sub ScanForPorts()
        Dim selPort As String = GetSelectedPortName()

        Dim lcv As New ListCollectionView(EIB.BusAccess.GetConnectionPorts)
        lcv.GroupDescriptions.Add(New PropertyGroupDescription("Category", New EIB.Converter.PortCategoryToStringConverter))

        cmbPorts.ItemsSource = lcv

        Dim index = -1
        For i = 0 To cmbPorts.Items.Count - 1
            If DirectCast(cmbPorts.Items(i), EIB.ConnectionPort).ID = selPort Then
                index = i
                Exit For
            End If
        Next

        If index = -1 Then
            selPort = New EIB.ConnectionPort(EIB.BusAccess.SimulatorName, EIB.ConnectionPortCategory.BCU2_PEI10_FT12).ID

            For i = 0 To cmbPorts.Items.Count - 1
                If DirectCast(cmbPorts.Items(i), EIB.ConnectionPort).ID = selPort Then
                    index = i
                    Exit For
                End If
            Next
        End If

        If index > -1 Then
            cmbPorts.SelectedIndex = index
        End If
    End Sub

    Private Function GetSelectedPortName() As String
        If cmbPorts.SelectedItem IsNot Nothing Then
            Return DirectCast(cmbPorts.SelectedItem, EIB.ConnectionPort).ID
        Else
            Return New EIB.ConnectionPort(EIB.BusAccess.SimulatorName, EIB.ConnectionPortCategory.BCU2_PEI10_FT12).ID
        End If
    End Function


    Private Sub lbLog_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles lbLog.SelectionChanged
        tbLogDetails.Tag = Nothing
        cmbDecodeEISType.DataContext = Nothing
        cmbDecodeDPTMainType.DataContext = Nothing
        cmbDecodeDPTSubType.DataContext = Nothing
        cmbDecodeEISType.IsEnabled = False
        cmbDecodeDPTMainType.IsEnabled = False
        cmbDecodeDPTSubType.IsEnabled = False
        btnDecodeEIS.IsEnabled = False
        btnDecodeDPT.IsEnabled = False
        txtDecodedEISData.Text = ""
        txtDecodedDPTData.Text = ""

        If lbLog.SelectedItem Is Nothing Then
            tbLogDetails.Text = ""
        Else
            If lbLog.SelectedItem Is Nothing OrElse Not TypeOf lbLog.SelectedItem Is EIBBusMessageLogBase OrElse DirectCast(lbLog.SelectedItem, EIBBusMessageLogBase).BusData Is Nothing Then
                tbLogDetails.Text = "No data"
            Else
                Dim info As New Text.StringBuilder

                Dim busdata As Byte() = DirectCast(lbLog.SelectedItem, EIBBusMessageLogBase).BusData
                Dim ft12 As EIB.Bus.FT12.FT12_FrameBase = Nothing

                Select Case EIB.Bus.FT12.FT12_FrameBase.GetFrameType(busdata)
                    Case EIB.Bus.FT12.FT12_FrameType.ACK
                        ft12 = New EIB.Bus.FT12.FT12_FrameACK(busdata)
                    Case EIB.Bus.FT12.FT12_FrameType.Fixed
                        ft12 = New EIB.Bus.FT12.FT12_FrameFixed(busdata)
                    Case EIB.Bus.FT12.FT12_FrameType.Variable
                        ft12 = New EIB.Bus.FT12.FT12_FrameVariable(busdata)

                        Dim EIBtype = EIB.Bus.EIBBusData_FrameBase.GetMessageType(DirectCast(ft12, EIB.Bus.FT12.FT12_FrameVariable).Data)

                        If EIBtype = EIB.BusData.EIBBusData_EMICode.L_Data_con OrElse
                           EIBtype = EIB.BusData.EIBBusData_EMICode.L_Data_ind OrElse
                           EIBtype = EIB.BusData.EIBBusData_EMICode.L_Data_req Then

                            Dim msg As New EIB.Bus.EIBBusData_FrameLData(DirectCast(ft12, EIB.Bus.FT12.FT12_FrameVariable).Data)
                            tbLogDetails.Tag = msg.Data
                            cmbDecodeEISType.DataContext = GetDecodableEISTypes(msg.Data.Length, True)
                            cmbDecodeDPTMainType.DataContext = GetDecodeableDPTMainTypes(msg.Data.Length, True)
                            cmbDecodeEISType.IsEnabled = True
                            cmbDecodeDPTMainType.IsEnabled = True
                        ElseIf EIBtype = EIB.BusData.EIBBusData_EMICode.L_Busmon_ind Then
                            Dim msg As New EIB.Bus.EIBBusData_FrameLBusMonData(DirectCast(ft12, EIB.Bus.FT12.FT12_FrameVariable).Data)
                            tbLogDetails.Tag = msg.Data
                            cmbDecodeEISType.DataContext = GetDecodableEISTypes(msg.Data.Length, True)
                            cmbDecodeDPTMainType.DataContext = GetDecodeableDPTMainTypes(msg.Data.Length, True)
                            cmbDecodeEISType.IsEnabled = True
                            cmbDecodeDPTMainType.IsEnabled = True
                        End If
                End Select

                If ft12 IsNot Nothing Then
                    Dim list As New List(Of EIB.InfoBase)

                    list.Add(New EIB.InfoList("FT12_Frame", "", ft12.ToInfoList))

                    info.Append(ft12.InfoListToString(list))
                Else
                    info.AppendLine("Invalid data")
                End If

                tbLogDetails.Text = info.ToString
            End If
        End If
    End Sub

    Private Sub btnWrite_Click(sender As Object, e As RoutedEventArgs) Handles btnWrite.Click
        WriteBusAddress(New EIB.Bus.Addressing.EIBGroupAddress(txtWriteAddress.Text), New EIBData.EIS.EIBDataEIS_1(cbWriteValue.IsChecked))
    End Sub

    Private Sub btnRead_Click(sender As Object, e As RoutedEventArgs) Handles btnRead.Click
        ReadBusAddress(New EIB.Bus.Addressing.EIBGroupAddress(txtReadAddress.Text))
    End Sub

    Private Sub btnReadForce_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles btnReadForce.Click
        ForceReadBusAddress(New EIB.Bus.Addressing.EIBGroupAddress(txtReadAddress.Text))
    End Sub

    Private Sub cmbDecodeEISType_SelectionChanged(sender As Object, e As System.Windows.Controls.SelectionChangedEventArgs) Handles cmbDecodeEISType.SelectionChanged
        If cmbDecodeEISType.SelectedItem IsNot Nothing Then
            btnDecodeEIS.IsEnabled = True
        Else
            btnDecodeEIS.IsEnabled = False
        End If
    End Sub

    Private Sub cmbDecodeDPTMainType_SelectionChanged(sender As Object, e As System.Windows.Controls.SelectionChangedEventArgs) Handles cmbDecodeDPTMainType.SelectionChanged
        If cmbDecodeDPTMainType.SelectedItem IsNot Nothing Then
            cmbDecodeDPTSubType.DataContext = GetDecodableDPTSubTypes(cmbDecodeDPTMainType.SelectedItem, True)
            cmbDecodeDPTSubType.IsEnabled = True
        Else
            cmbDecodeDPTSubType.DataContext = Nothing
            cmbDecodeDPTSubType.IsEnabled = False
        End If
    End Sub

    Private Sub cmbDecodeDPTSubType_SelectionChanged(sender As Object, e As System.Windows.Controls.SelectionChangedEventArgs) Handles cmbDecodeDPTSubType.SelectionChanged
        If cmbDecodeDPTSubType.SelectedItem IsNot Nothing Then
            btnDecodeDPT.IsEnabled = True
        Else
            btnDecodeDPT.IsEnabled = False
        End If
    End Sub

    Private Sub btnDecodeEIS_Click(sender As Object, e As System.Windows.RoutedEventArgs) Handles btnDecodeEIS.Click
        If tbLogDetails.Tag IsNot Nothing AndAlso TypeOf tbLogDetails.Tag Is Byte() Then
            Dim dec As EIBData.EIS.EIBDataEIS_Base = Activator.CreateInstance(DirectCast(cmbDecodeEISType.SelectedItem, EIBData.EIBDataEIS_Info).EIS_Type, tbLogDetails.Tag)
            Dim list As New List(Of EIB.InfoBase)

            list.Add(New EIB.InfoList("EIBDataEIS", "", dec.ToInfoList))

            txtDecodedEISData.Text = dec.InfoListToString(list)
        Else
            txtDecodedEISData.Text = "- decoding failed -"
        End If
    End Sub

    Private Sub btnDecodeDPT_Click(sender As Object, e As RoutedEventArgs) Handles btnDecodeDPT.Click
        If tbLogDetails.Tag IsNot Nothing AndAlso TypeOf tbLogDetails.Tag Is Byte() Then
            Dim dec As EIBData.DPT.EIBDataDPT_Base = Activator.CreateInstance(DirectCast(cmbDecodeDPTSubType.SelectedItem, EIBData.EIBDataDPT_Info).DPT_Type, tbLogDetails.Tag)
            Dim list As New List(Of EIB.InfoBase)

            list.Add(New EIB.InfoList("EIBDataDPT", "", dec.ToInfoList))

            txtDecodedDPTData.Text = dec.InfoListToString(list)
        Else
            txtDecodedDPTData.Text = "- decoding failed -"
        End If
    End Sub

    Private Sub mnuClose_Click(sender As Object, e As RoutedEventArgs) Handles mnuClose.Click
        Disconnect()
    End Sub

    Private Sub mnuSaveAsText_Click(sender As Object, e As RoutedEventArgs) Handles mnuSaveAsText.Click
        Dim sfd As New SaveFileDialog
        sfd.Title = "Save As Text file..."
        sfd.Filter = "Text file (*.txt)|*.txt|All files|*.*"

        If sfd.ShowDialog(Me) Then
            Using sw As New IO.StreamWriter(sfd.FileName)
                For Each lmb As EIBBusMessageLogBase In Logger
                    sw.WriteLine(lmb.Message)
                Next
            End Using
        End If
    End Sub

    Private Sub mnuSaveAsHex_Click(sender As Object, e As RoutedEventArgs) Handles mnuSaveAsHex.Click
        Dim sfd As New SaveFileDialog
        sfd.Title = "Save As Hex file..."
        sfd.Filter = "Hex file (*.hex)|*.hex|Text file (*.txt)|*.txt|All files|*.*"

        If sfd.ShowDialog(Me) Then
            Using sw As New IO.StreamWriter(sfd.FileName)
                For Each lmb As EIBBusMessageLogBase In Logger
                    If lmb.BusData IsNot Nothing Then
                        sw.WriteLine(EIB.Helper.HexConverters.ConvertByteArrayToHexString(lmb.BusData))
                    End If
                Next
            End Using
        End If
    End Sub

    Private Sub mnuLoadFromHex_Click(sender As Object, e As RoutedEventArgs) Handles mnuLoadFromHex.Click
        Dim ofd As New OpenFileDialog
        ofd.Title = "Open Hex file..."
        ofd.Filter = "Hex file (*.hex)|*.hex|Text file (*.txt)|*.txt|All files|*.*"

        If ofd.ShowDialog(Me) Then
            Logger.Clear()

            Using sr As New IO.StreamReader(ofd.FileName)
                While Not sr.EndOfStream
                    Dim data = sr.ReadLine()

                    AddLogEntry(EIB.Helper.HexConverters.ConvertHexStringToByteArray(data), data)
                End While
            End Using
        End If
    End Sub

    Private Sub mnuAbout_Click(sender As Object, e As RoutedEventArgs) Handles mnuAbout.Click
        Dim aboutWin As New AboutWindow

        aboutWin.ShowDialog()
    End Sub

    Private Sub mnuConnect_Click(sender As Object, e As RoutedEventArgs) Handles mnuConnect.Click
        Connect(cmbPorts.SelectedItem)
    End Sub

    Private Sub mnuDisconnect_Click(sender As Object, e As RoutedEventArgs) Handles mnuDisconnect.Click
        Disconnect()
    End Sub

    Private Sub mnuLinkStatus_Click(sender As Object, e As RoutedEventArgs) Handles mnuLinkStatus.Click
        _busManager.GetLinkStatus()
    End Sub

    Private Sub mnuResetBCU_Click(sender As Object, e As RoutedEventArgs) Handles mnuResetBCU.Click
        _busManager.ResetBCU()
    End Sub

    Private Sub mnuRead_Click(sender As Object, e As RoutedEventArgs) Handles mnuRead.Click
        tcOptions.SelectedIndex = 1
    End Sub

    Private Sub mnuWrite_Click(sender As Object, e As RoutedEventArgs) Handles mnuWrite.Click
        tcOptions.SelectedIndex = 2
    End Sub

    Private Sub btnBusMonTest_Click(sender As Object, e As RoutedEventArgs) Handles btnBusMonTest.Click
        Dim msg As New EIB.Bus.EIBBusData_FrameLBusMonData(False, False, False, False, True, 5, 287, EIB.BusData.EIBBusData_FrameRepeatFlag.NewData, EIB.BusData.EIBBusData_FramePriority.Normal, New EIB.Bus.Addressing.EIBGroupAddress("5/5/0"), 6, 0, EIB.BusData.EIBBusData_FrameACPI_L_Data_Type.Write, New Byte() {0})
        Dim ft12 As New EIB.Bus.FT12.FT12_FrameVariable(EIB.Bus.FT12.FT12_FrameDirection.BAUtoPC, True, True, EIB.Bus.FT12.FT12_FramePrimaryMessageCode.SEND_UDAT, msg.BusData)
        
        _busManager_LogBusData(EIB.Bus.EIBBusAccessLogReason.IncomingMessage, "", ft12.BusData)
    End Sub

    Private Sub btnConnect_Click(sender As Object, e As RoutedEventArgs) Handles btnConnect.Click
        Connect(cmbPorts.SelectedItem)
    End Sub

    Private Sub btnDisconnect_Click(sender As Object, e As RoutedEventArgs) Handles btnDisconnect.Click
        Disconnect()
    End Sub
End Class
